"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

from PyQt4 import QtCore
from msnp import gui
from msnp.logger import Logger
from msnp.service import network
from msnp.model import PTPModel
from msnp.gui.widgets.AudioWidget import AudioListWidget
from msnp.persistence import XMLController, PersistenceController
from msnp.gui import GUIHelper
from msnp.service.network.listening import Listener
from msnp.service.synch import timer

#############
## SIGNALS ##
#############

class AuthFinishedSignal(QtCore.QObject):
    """A signal of this type is emitted when the authentication process is finished.
    
    Parameters:
        __returnType: A ReturnType object, one of "ERROR", "SUCCESSFUL", "LOGIN_WRONG_USERNAME",
                "LOGIN_WRONG_PASSWORD", "REGISTER_NAME_NOT_AVAILABLE", "AUTHENTICATION_NO_PASSWORD" or "ALREADY_LOGGED_IN".
        __authFinishedSignal: A pyqtSignal object connected to the method authFinishedSlot().
    """
    __authFinishedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__returnType = None
        self.__authFinishedSignal.connect(self.authFinishedSlot)
        
    def authFinishedSlot(self):
        """This method is called when the pyqtSignal object __authFinishedSignal is emitted."""
        Logger.guiInfo('executing authfinished signal')
        if self.__returnType == None or self.__returnType == PTPModel.ReturnType.SUCCESSFUL:
            groups = network.NetworkController.getGroupsIAmMember()
            Logger.info("got " + str(len(groups)) + " groups")
            network.NetworkController.pollMediaContentSinceLastSynch(groups)
            gui.GUIController.getStartWidget().setVisible(False)
            gui.GUIController.openGroupCollection(groups)
            #start synch changes timer
            settings = XMLController.readAllSettings()
            if settings.getCurrentUserSettings().getPlayerDatabaseSettings().isComplete():
                timer.SynchChangesTimer.startSynchChangesTimer()
            else:
                gui.GUIController.getGroupCollectionWidget().showPlayerDBNotSetDialog()
        else:
            Listener.ListeningThread.stopListening()
            gui.GUIController.closeWidgets()
            gui.GUIController.getStartWidget().buildLoginWidget()
            gui.GUIController.getStartWidget().setVisible(True)
            gui.GUIController.getStartWidget().showAuthFailedDialog(gui.GUIHelper.returnTypeToString(self.__returnType))
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __authFinishedSignal."""
        self.__authFinishedSignal.emit()
        
    def setReturnType(self, retType):
        """This method sets the parameter __returnType to the given value."""
        self.__returnType = retType
        
        
class SearchGroupResultReceivedSignal(QtCore.QObject):
    """A signal of this type is emitted when results for the group search process are received.
    
    Parameters:
        __receivedGroups: A list of Group object representing the found groups.
        __searchGroupResultReceivedSignal: A pyqtSignal object connected to the method searchGroupResultReceived().
    """
    __searchGroupResultReceivedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__searchGroupResultReceivedSignal.connect(self.searchGroupResultReceived)
        self.__receivedGroups = []
        
    def searchGroupResultReceived(self):
        """This method is called when the pyqtSignal object __searchGroupResultReceivedSignal is emitted."""
        if self.__receivedGroups != None and len(self.__receivedGroups) > 0:
            for group in self.__receivedGroups:
                Logger.info("Received new Group: " + group.getGroupname())
                widget = gui.GUIController.getGroupWidget().getSearchWidget()
                if widget != None:
                    widget.addSearchResult(group)
                self.__receivedGroups.remove(group)
        else:
            Logger.info("__receivedGroup None in searchGroupResultReceived")
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __searchGroupResultReceivedSignal."""
        self.__searchGroupResultReceivedSignal.emit()
        
    def addReceivedGroup(self, group):
        """This method appends the given list of Groups to the parameter __receivedGroups."""
        self.__receivedGroups.append(group)
        
        
class SearchGroupFinishedSignal(QtCore.QObject):
    """A signal of this type is emitted when the group search process is finished.
    
    Parameters:
        __searchGroupFinishedSignal: A pyqtSignal object connected to the method searchGroupFinished().
    """
    __searchGroupFinishedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__searchGroupFinishedSignal.connect(self.searchGroupFinished)
        
    def searchGroupFinished(self):
        """This method is called when the pyqtSignal object __searchGroupFinishedSignal is emitted."""
        Logger.info("Group search finished")
        searchWidget = gui.GUIController.getGroupWidget().getSearchWidget()
        if searchWidget != None:
            searchWidget.stopLoadingMovie()
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __searchGroupFinishedSignal."""
        self.__searchGroupFinishedSignal.emit()
        
        
class SearchGroupDetailsFinishedSignal(QtCore.QObject):
    """A signal of this type is emitted when the search for certain group details is finished.
    
    Parameters:
        __receivedGroup: A Group object representing the found group.
        __searchGroupDetailsFinishedSignal: A pyqtSignal object connected to the method searchGroupDetailsFinished().
    """
    __searchGroupDetailsFinishedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__searchGroupDetailsFinishedSignal.connect(self.searchGroupDetailsFinished)
        self.__receivedGroup = None
        
    def searchGroupDetailsFinished(self):
        """This method is called when the pyqtSignal object __searchGroupDetailsFinishedSignal is emitted."""
        if self.__receivedGroup != None:
            Logger.info("Received details for Group: " + self.__receivedGroup.getGroupname())
            #decide between not_member, member and owner... in the case of new_group no searchGroupDetailsFinished signal is triggered
            myName = network.NetworkController.getMySelf().getMyIdentity().getName()
            groupDetailType = gui.GUIHelper.GroupDetailType.NOT_MEMBER
            if self.__receivedGroup.getOwnername() == myName:
                groupDetailType = gui.GUIHelper.GroupDetailType.OWNER
            elif self.__receivedGroup.getMembers() != None and len(self.__receivedGroup.getMembers()) > 0:
                for member in self.__receivedGroup.getMembers():
                    if member.getName() == myName and member.getStatus() != PTPModel.MemberStatus.DELETED:
                        groupDetailType = gui.GUIHelper.GroupDetailType.MEMBER
                        break
            gui.GUIController.getGroupWidget().buildGroupDetailWidget(groupDetailType, self.__receivedGroup)
            self.__receivedGroup = None
        else:
            Logger.info("__receivedGroup None in searchGroupDetailsFinished")
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __searchGroupDetailsFinishedSignal."""
        self.__searchGroupDetailsFinishedSignal.emit()
        
    def setReceivedGroup(self, group):
        """This method sets the parameters __receivedGroup to the given one."""
        self.__receivedGroup = group
        
        
class SynchEnableSignal(QtCore.QObject):
    """A signal of this type is emitted when synchronization towards the media player changes to enabled/disabled.
    
    Parameters:
        __enable: A boolean value, True if synchronization is now enabled, False if synchronization is now disabled.
        __synchToPlayerDB: A boolean value, True if the synchronization from the media database to the media player is affected.
        __errorType: A ReturnType object, one of SUCCESSFUL or NO_PLAYER_SELECTED.
        __synchEnableSignal: A pyqtSignal object connected to the method synchEnable().
    """
    __synchEnableSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__enable = False
        self.__synchToPlayerDB = True
        self.__errorType = PTPModel.ReturnType.SUCCESSFUL
        self.__synchEnableSignal.connect(self.synchEnable)
        
    def synchEnable(self):
        """This method is called when the pyqtSignal object __synchEnableSignal is emitted."""
        if self.__errorType == PTPModel.ReturnType.SUCCESSFUL:
            Logger.info("player enable signal " + str(self.__enable))
            if self.__enable and self.__synchToPlayerDB == False:
                gui.GUIController.getGroupCollectionWidget().showSynchFinishedDialog()
            gui.GUIController.getGroupCollectionWidget().enableSynchronization(self.__enable)
            if gui.GUIController.getSettingsWidget() != None:
                gui.GUIController.getSettingsWidget().enableSynchronization(self.__enable)
        else:
            gui.GUIController.getGroupCollectionWidget().showErrorDialog(GUIHelper.returnTypeToString(self.__errorType))
            self.__errorType = None
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __synchEnableSignal."""
        self.__synchEnableSignal.emit()
        
    def setEnabled(self, enable):
        """This method sets the parameters __enable to the given one."""
        self.__enable = enable
        
    def setSynchToPlayerDB(self, synchToPlayerDB):
        """This method sets the parameters __synchToPlayerDB to the given one."""
        self.__synchToPlayerDB = synchToPlayerDB
        
    def setErrorType(self, errorType):
        """This method sets the parameters __errorType to the given one."""
        self.__errorType = errorType
        
class RefreshGroupListSignal(QtCore.QObject):
    """A signal of this type is emitted when the list of groups where the user is a member of changes, i.e. if the user leaves/joins a group.
    
    Parameters:
        __group: A Group object containing the group where the user joined/leaved.
        __remove: A boolean value, True if the user leaved and the group has to be removed from the list, False if the user joined and the group has to be added to the list.
        __refreshGroupListSignal: A pyqtSignal object connected to the method refreshGroupList().
    """
    __refreshGroupListSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__refreshGroupListSignal.connect(self.refreshGroupList)
        self.__group = None
        self.__remove = False

    def setGroup(self, group, remove):
        """This method sets the parameters __group and __remove to the given ones."""
        self.__group = group
        self.__remove = remove

    def refreshGroupList(self):
        """This method is called when the pyqtSignal object __refreshGroupListSignal is emitted."""
        if self.__remove:
            Logger.info("group leaved")
        else:
            Logger.info("new group joined")
        gui.GUIController.getGroupCollectionWidget().refreshGroupList(self.__group, self.__remove)
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __refreshGroupListSignal."""
        self.__refreshGroupListSignal.emit()
        
class MsgReceivedSignal(QtCore.QObject):
    """A signal of this type is emitted when a message sent by the application to the user arrives.
    
    Parameters:
        __message: A Message object containing the received message.
        __msgReceivedSignal: A pyqtSignal object connected to the method msgReceived().
    """
    __msgReceivedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__msgReceivedSignal.connect(self.msgReceived)
        self.__messages = None
    
    def setMessages(self, messages):
        """This method sets the parameter __messages to the given one."""
        self.__messages = messages
    
    def msgReceived(self):
        """This method is called when the pyqtSignal object __msgReceivedSignal is emitted."""
        msgWidget = gui.GUIController.getMessageWidget()
        if self.__messages == None:
            if msgWidget == None:
                gui.GUIController.getGroupCollectionWidget().refreshBtnMessages()
            else:
                network.NetworkController.getStoredMessages()
        else:
            if msgWidget != None:
                msgWidget.newMessages(self.__messages)
            self.__messages = None
    
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __msgReceivedSignal."""
        self.__msgReceivedSignal.emit()
    
class UpdateProgressBarSignal(QtCore.QObject):
    """A signal of this type is emitted when the progress bar has to be updated, i.e. when the synchronization processed one entry completely.
    
    Parameters:
        __progressCount: An integer value representing the progress of the bar.
        __updateProgressBarSignal: A pyqtSignal object connected to the method updateProgressBar().
    """
    __updateProgressBarSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__progressCount = -1
        self.__updateProgressBarSignal.connect(self.updateProgressBar)
        
    def updateProgressBar(self):
        """This method is called when the pyqtSignal object __updateProgressBarSignal is emitted."""
        Logger.info("update progress bar")
        if self.__progressCount > 0 and gui.GUIController.getProgressBar() != None:
            gui.GUIController.getProgressBar().updateProgressBar(self.__progressCount)
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __updateProgressBarSignal."""
        self.__updateProgressBarSignal.emit()
        
    def setProgressCount(self, progressCount):
        """This method sets the parameter __progressCount to the given one."""
        self.__progressCount = progressCount
        
class OpenProgressBarSignal(QtCore.QObject):
    """A signal of this type is emitted when the progress bar should be displayed.
    
    Parameters:
        __max: An integer value representing the maximum number to which the progress bar should count (the number that represents 100%).
        __isModal: A boolean value, True if the other windows should be blocked, False otherwise.
        __openProgressBarSignal: A pyqtSignal object connected to the method __openProgressBarSignal().
    """
    __openProgressBarSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__max = -1
        self.__isModal = True
        self.__openProgressBarSignal.connect(self.openProgressBar)
        
    def openProgressBar(self):
        """This method is called when the pyqtSignal object __openProgressBarSignal is emitted."""
        Logger.info("open progress bar")
        if self.__max > 0:
            gui.GUIController.openProgressBar(self.__max, self.__isModal)
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __openProgressBarSignal."""
        self.__openProgressBarSignal.emit()
        
    def setMaxValue(self, max):
        """This method sets the parameter __max to the given one."""
        self.__max = max
        
    def setModal(self, isModal):
        """This method sets the parameter __isModal to the given one."""
        self.__isModal = isModal
        

class AudiosRetrievedSignal(QtCore.QObject):
    """A signal of this type is emitted when all audios were retrieved from the media database.
    
    Parameters:
        __audios: A list of Audio objects to be displayed.
        __audiosRetrievedSignal: A pyqtSignal object connected to the method __audiosRetrievedSignal().
    """
    __audiosRetrievedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__audios = None
        self.__audiosRetrievedSignal.connect(self.audiosRetrieved)
        
    def audiosRetrieved(self):
        """This method is called when the pyqtSignal object __audiosRetrievedSignal is emitted."""
        Logger.info("audios retrieved")
        tableWidget = AudioListWidget(self.__audios)
        gui.GUIController.getAudioTableWidget().buildAudioTableWidget(tableWidget)
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __audiosRetrievedSignal."""
        self.__audiosRetrievedSignal.emit()
        
    def setAudios(self, audios):
        """This method sets the parameter __audios to the given one."""
        self.__audios = audios
        
        
class ChatMessageReceivedSignal(QtCore.QObject):
    """A signal of this type is emitted when a chat message sent by another user to this user is received.
    
    Parameters:
        __chatMessage: The received chat message.
        __chatMessageReceivedSignal: A pyqtSignal object connected to the method chatMessageReceived().
    """
    __chatMessageReceivedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__chatMessage = None
        self.__chatMessageReceivedSignal.connect(self.chatMessageReceived)
        
    def chatMessageReceived(self):
        """This method is called when the pyqtSignal object __chatMessageReceivedSignal is emitted."""
        Logger.info("new chat message received")
        if self.__chatMessage != None:
            chatWidget = gui.GUIController.getPersonalMessageWidget(self.__chatMessage.getSendername())
            settings = XMLController.readAllSettings()
            username = settings.getCurrentUserSettings().getUsername()
            PersistenceController.insertChatMessage(username, self.__chatMessage.getSendername(), self.__chatMessage)
            if chatWidget != None:
                chatWidget.changeHappened()
            else:
                gui.GUIController.openPersonalMessageWidget(self.__chatMessage.getSendername())
        else:
            Logger.info("chat message none")
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __chatMessageReceivedSignal."""
        self.__chatMessageReceivedSignal.emit()
        
    def setChatMessage(self, message):
        """This method sets the parameter __chatMessage to the given one."""
        self.__chatMessage = message
        
        
class ChatMessageStatusChangedSignal(QtCore.QObject):
    """A signal of this type is emitted when the status of a chat message changes.
    
    Parameters:
        __timestamp: A float value containing the exact timestamp when the message was sent.
        __status: A ChatMessageStatus object, one of "RECEIVED", "SENDING", "SENT", "PEER_OFFLINE" or "PEER_NOT_EXISTENT".
        __senderName: A String containing the name of the sender.
        __chatMessageStatusChangedSignal: A pyqtSignal object connected to the method chatMessageStatusChanged().
    """
    __chatMessageStatusChangedSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__timestamp = None
        self.__status = None
        self.__senderName = None
        self.__chatMessageStatusChangedSignal.connect(self.chatMessageStatusChanged)
        
    def chatMessageStatusChanged(self):
        """This method is called when the pyqtSignal object __chatMessageStatusChangedSignal is emitted."""
        Logger.info("chat message status changed")
        if self.__timestamp != None and self.__status != None and self.__senderName != None:
            chatWidget = gui.GUIController.getPersonalMessageWidget(self.__senderName)
            if chatWidget != None:
                settings = XMLController.readAllSettings()
                username = settings.getCurrentUserSettings().getUsername()
                PersistenceController.updateChatMessageForSendernameAndTimestamp(username, self.__timestamp, self.__status)
                chatWidget.changeHappened()
            else:
                Logger.info("no chat open with sendername " + self.__senderName + " -> ignore the status change.")
        else:
            Logger.info("timestamp or status or senderName none")
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __chatMessageStatusChangedSignal."""
        self.__chatMessageStatusChangedSignal.emit()
        
    def setTimestamp(self, timestamp):
        """This method sets the parameter __timestamp to the given one."""
        self.__timestamp = timestamp
        
    def setStatus(self, status):
        """This method sets the parameter __status to the given one."""
        self.__status = status
        
    def setSendername(self, senderName):
        """This method sets the parameter __senderName to the given one."""
        self.__senderName = senderName
        
        
class RestartPlayerSignal(QtCore.QObject):
    """A signal of this type is emitted when the media player has to be restarted and a dialog should be displayed to the user.
    
    Parameters:
        __restartPlayerSignal: A pyqtSignal object connected to the method restartPlayer().
    """
    __restartPlayerSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__restartPlayerSignal.connect(self.restartPlayer)
        
    def restartPlayer(self):
        """This method is called when the pyqtSignal object __restartPlayerSignal is emitted."""
        Logger.info("restart player signal emitted")
        gui.GUIController.getGroupCollectionWidget().showRestartPlayerDialog()
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __restartPlayerSignal."""
        self.__restartPlayerSignal.emit()
        
class DatabaseExceptionOccurredSignal(QtCore.QObject):
    """A signal of this type is emitted when an exception occurred in the database.
    
    Parameters:
        __dbErrorType: A DBErrorType object, one of SELECT, INSERT, UPDATE, DELETE, INIT, CHECK, DROP, TRIGGER or UNKNOWN.
        __dbType: A DatabaseType object, one of MEDIA, PLAYER or PTP.
        __traceback: A String object containing the traceback text of the error.
        __dbExceptionOccurredSignal: A pyqtSignal object connected to the method dbException().
    """
    __dbExceptionOccurredSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__dbType = None
        self.__dbErrorType = None
        self.__traceback = None
        self.__dbExceptionOccurredSignal.connect(self.dbException)
        
    def dbException(self):
        """This method is called when the pyqtSignal object __dbExceptionOccurredSignal is emitted."""
        Logger.info("db exception signal emitted")
        if self.__dbErrorType != None and self.__dbType != None and self.__traceback != None:
            gui.GUIController.openDBErrorWidget(self.__dbType, self.__dbErrorType, self.__traceback)
            
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __dbExceptionOccurredSignal."""
        self.__dbExceptionOccurredSignal.emit()
        
    def setDBErrorType(self, type):
        """This method sets the parameter __dbErrorType to the given one."""
        self.__dbErrorType = type
        
    def setDBType(self, dbType):
        """This method sets the parameter __dbType to the given one."""
        self.__dbType = dbType
        
    def setTraceback(self, traceback):
        """This method sets the parameter __traceback to the given one."""
        self.__traceback = traceback
        
class NothingToSynchSignal(QtCore.QObject):
    """A signal of this type is emitted when there is nothing to synchronize from the media database towards the media player.
    
    Parameters:
        __nothingToSynchSignal: A pyqtSignal object connected to the method showNothingToSynchDialog().
    """
    __nothingToSynchSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__nothingToSynchSignal.connect(self.showNothingToSynchDialog)
        
    def showNothingToSynchDialog(self):
        """This method is called when the pyqtSignal object __nothingToSynchSignal is emitted."""
        Logger.info("nothing to synch signal emitted")
        gui.GUIController.getGroupCollectionWidget().showNothingToSynchDialog()
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __nothingToSynchSignal."""
        self.__nothingToSynchSignal.emit()
        
class ConnectionLostSignal(QtCore.QObject):
    """A signal of this type is emitted when the application lost the internet connection.
    
    Parameters:
        __connectionLostSignal: A pyqtSignal object connected to the method connectionLost().
    """
    __connectionLostSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__connectionLostSignal.connect(self.connectionLost)
        
    def connectionLost(self):
        """This method is called when the pyqtSignal object __connectionLostSignal is emitted."""
        Logger.info("connection lost signal emitted")
        gui.GUIController.closeWidgets()
        gui.GUIController.getStartWidget().buildLoginWidget()
        gui.GUIController.getStartWidget().setVisible(True)
        gui.GUIController.getStartWidget().showConnectionLostDialog()
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __connectionLostSignal."""
        self.__connectionLostSignal.emit()


class LogoutSignal(QtCore.QObject):
    """A signal of this type is emitted when the application logged out from the network.
    
    Parameters:
        __logoutSignal: A pyqtSignal object connected to the method logout().
    """
    __logoutSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__logoutSignal.connect(self.logout)
        
    def logout(self):
        """This method is called when the pyqtSignal object __logoutSignal is emitted."""
        Logger.info("logout signal emitted")
        gui.GUIController.closeWidgets()
        gui.GUIController.getStartWidget().buildLoginWidget()
        gui.GUIController.getStartWidget().setVisible(True)
        
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __logoutSignal."""
        self.__logoutSignal.emit()

class LogoutEnabledSignal(QtCore.QObject):
    """A signal of this type is emitted when the user is now able to log out (when logged in) or when the user is not able to log out (when it is not logged in).
    
    Parameters:
        __enable: A boolean value, True if logging out is enabled, False otherwise.
        __logoutEnabledSignal: A pyqtSignal object connected to the method logoutEnabled().
    """
    __logoutEnabledSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__enable = False
        self.__logoutEnabledSignal.connect(self.logoutEnabled)
    
    def logoutEnabled(self):
        """This method is called when the pyqtSignal object __logoutEnabledSignal is emitted."""
        Logger.info("logout enabled signal emitted")
        gui.GUIController.getSystemTray().enableLogout(self.__enable)
    
    def setEnabled(self, enable):
        """This method sets the parameter __enable to the given one."""
        self.__enable = enable
    
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __logoutEnabledSignal."""
        self.__logoutEnabledSignal.emit()
        
class GroupsWithMembersToConfirmSignal(QtCore.QObject):
    """A signal of this type is emitted when the groups, where the user has to confirm memberships, are retrieved.
    
    Parameters:
        __groups: A list of Group objects.
        __groupsWithMembersToConfirmSignal: A pyqtSignal object connected to the method groupsWithMembersToConfirm().
    """
    __groupsWithMembersToConfirmSignal = QtCore.pyqtSignal()
    
    def __init__(self):
        """The init-method."""
        QtCore.QObject.__init__(self)
        self.__groups = None
        self.__groupsWithMembersToConfirmSignal.connect(self.groupsWithMembersToConfirm)
        
    def groupsWithMembersToConfirm(self):
        """This method is called when the pyqtSignal object __groupsWithMembersToConfirmSignal is emitted."""
        gui.GUIController.getConfirmWidget().buildConfirmWidget(self.__groups)
        
    def setGroups(self, groups):
        """This method sets the parameter __groups to the given one."""
        self.__groups = groups
    
    def emit(self):
        """This method calls the method emit() of the pyqtSignal object __groupsWithMembersToConfirmSignal."""
        self.__groupsWithMembersToConfirmSignal.emit()
        
###############
## INSTANCES ##
###############
    
__authFinishedSignalInstance = AuthFinishedSignal()
__searchGroupReceivedSignalInstance = SearchGroupResultReceivedSignal()
__searchGroupFinishedSignalInstance = SearchGroupFinishedSignal()
__searchGroupDetailsFinishedSignalInstance = SearchGroupDetailsFinishedSignal()
__synchEnableSignalInstance = SynchEnableSignal()
__refreshGroupListSignalInstance = RefreshGroupListSignal()
__msgReceivedSignalInstance = MsgReceivedSignal()
__updateProgressBarSignalInstance = UpdateProgressBarSignal()
__openProgressBarSignalInstance = OpenProgressBarSignal()
__audiosRetrievedSignalInstance = AudiosRetrievedSignal()
__chatMessageReceivedSignalInstance = ChatMessageReceivedSignal()
__chatMessageStatusChangedSignalInstance = ChatMessageStatusChangedSignal()
__restartPlayerSignalInstance = RestartPlayerSignal()
__dbExceptionOccurredSignalInstance = DatabaseExceptionOccurredSignal()
__nothingToSynchSignalInstance = NothingToSynchSignal()
__connectionLostSignalInstance = ConnectionLostSignal()
__logoutSignalInstance = LogoutSignal()
__logoutEnabledSignalInstance = LogoutEnabledSignal()
__groupsWithMembersToConfirmSignalInstance = GroupsWithMembersToConfirmSignal()

##################
## EMIT-METHODS ##
##################

def emitAuthFinishedSignal(returnType):
    """This function emits an AuthFinishedSignal."""
    global __authFinishedSignalInstance
    if gui.GUIController.isGUI():
        __authFinishedSignalInstance.setReturnType(returnType)
        return __authFinishedSignalInstance.emit()

def emitSearchGroupReceivedSignal(group):
    """This function emits a SearchGroupReceivedSignal."""
    global __searchGroupReceivedSignalInstance
    if gui.GUIController.isGUI():
        __searchGroupReceivedSignalInstance.addReceivedGroup(group)
        return __searchGroupReceivedSignalInstance.emit()

def emitSearchGroupFinishedSignal():
    """This function emits a SearchGroupFinishedSignal."""
    global __searchGroupFinishedSignalInstance
    if gui.GUIController.isGUI():
        return __searchGroupFinishedSignalInstance.emit()

def emitSearchGroupDetailsFinishedSignal(group):
    """This function emits a SearchGroupDetailsFinishedSignal."""
    global __searchGroupDetailsFinishedSignalInstance
    if gui.GUIController.isGUI():
        __searchGroupDetailsFinishedSignalInstance.setReceivedGroup(group)
        return __searchGroupDetailsFinishedSignalInstance.emit()

def emitSynchEnableSignal(enable, synchToPlayerDB, returnType):
    """This function emits a SynchEnableSignal."""
    global __synchEnableSignalInstance
    if gui.GUIController.isGUI():
        __synchEnableSignalInstance.setEnabled(enable)
        __synchEnableSignalInstance.setSynchToPlayerDB(synchToPlayerDB)
        __synchEnableSignalInstance.setErrorType(returnType)
        return __synchEnableSignalInstance.emit()

def emitRefreshGroupListSignal(group, remove=False):
    """This function emits a RefreshGroupListSignal."""
    global __refreshGroupListSignalInstance
    if gui.GUIController.isGUI():
        __refreshGroupListSignalInstance.setGroup(group, remove)
        return __refreshGroupListSignalInstance.emit()

def emitMsgReceivedSignal(messages=None):
    """This function emits a MsgReceivedSignal."""
    global __msgReceivedSignalInstance
    if gui.GUIController.isGUI():
        __msgReceivedSignalInstance.setMessages(messages)
        return __msgReceivedSignalInstance.emit()
    
def emitUpdateProgressBarSignal(progressCount):
    """This function emits an UpdateProgressBarSignal."""
    global __updateProgressBarSignalInstance
    if gui.GUIController.isGUI():
        __updateProgressBarSignalInstance.setProgressCount(progressCount)
        return __updateProgressBarSignalInstance.emit()

def emitOpenProgressBarSignal(max, isModal):
    """This function emits an OpenProgressBarSignal."""
    global __openProgressBarSignalInstance
    if gui.GUIController.isGUI():
        __openProgressBarSignalInstance.setMaxValue(max)
        __openProgressBarSignalInstance.setModal(isModal)
        return __openProgressBarSignalInstance.emit()

def emitAudiosRetrievedSignal(audios):
    """This function emits an AudiosRetrievedSignal."""
    global __audiosRetrievedSignalInstance
    if gui.GUIController.isGUI():
        __audiosRetrievedSignalInstance.setAudios(audios)
        return __audiosRetrievedSignalInstance.emit()

def emitChatMessageReceivedSignal(chatMessage):
    """This function emits a ChatMessageReceivedSignal."""
    global __chatMessageReceivedSignalInstance
    if gui.GUIController.isGUI():
        __chatMessageReceivedSignalInstance.setChatMessage(chatMessage)
        return __chatMessageReceivedSignalInstance.emit()

def emitChatMessageStatusChangedSignal(timestamp, newStatus, senderName):
    """This function emits a ChatMessageStatusChangedSignal."""
    global __chatMessageStatusChangedSignalInstance
    if gui.GUIController.isGUI():
        __chatMessageStatusChangedSignalInstance.setTimestamp(timestamp)
        __chatMessageStatusChangedSignalInstance.setStatus(newStatus)
        __chatMessageStatusChangedSignalInstance.setSendername(senderName)
        return __chatMessageStatusChangedSignalInstance.emit()

def emitRestartPlayerSignal():
    """This function emits a RestartPlayerSignal."""
    global __restartPlayerSignalInstance
    if gui.GUIController.isGUI():
        return __restartPlayerSignalInstance.emit()

def emitDBExceptionOccurredSignal(errorType, dbType, traceback):
    """This function emits a DatabaseExceptionOccurredSignal."""
    global __dbExceptionOccurredSignalInstance
    if gui.GUIController.isGUI():
        __dbExceptionOccurredSignalInstance.setDBErrorType(errorType)
        __dbExceptionOccurredSignalInstance.setDBType(dbType)
        __dbExceptionOccurredSignalInstance.setTraceback(traceback)
        return __dbExceptionOccurredSignalInstance.emit()

def emitNothingToSynchSignal():
    """This function emits a NothingToSynchSignal."""
    global __nothingToSynchSignalInstance
    if gui.GUIController.isGUI():
        return __nothingToSynchSignalInstance.emit()

def emitConnectionLostSignal():
    """This function emits a ConnectionLostSignal."""
    global __connectionLostSignalInstance
    if gui.GUIController.isGUI():
        return __connectionLostSignalInstance.emit()

def emitLogoutSignal():
    """This function emits a LogoutSignal."""
    global __logoutSignalInstance
    if gui.GUIController.isGUI():
        return __logoutSignalInstance.emit()

def emitLogoutEnabledSignal(enable):
    """This function emits a LogoutEnabledSignal."""
    global __logoutEnabledSignalInstance
    if gui.GUIController.isGUI():
        __logoutEnabledSignalInstance.setEnabled(enable)
        return __logoutEnabledSignalInstance.emit()

def emitGroupsWithMembersToConfirmSignal(groups):
    """This function emits a GroupsWithMembersToConfirmSignal."""
    global __groupsWithMembersToConfirmSignalInstance
    if gui.GUIController.isGUI():
        __groupsWithMembersToConfirmSignalInstance.setGroups(groups)
        return __groupsWithMembersToConfirmSignalInstance.emit()

